package Stream;

import java.util.ArrayList;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * collect()函数demo
 * <R> R collect(Supplier<R> supplier,
 *                BiConsumer<R, ? super T> accumulator,
 *                BiConsumer<R, R> combiner)
 * collect()与三参数reduce()有点相似，区别是每个并行分段都会拥有一个新的supplier，这是一个容器，accumulator
 * 的结果会存在这个容器，并行结果也会由第二个容器中的值add到第一个容器
 */
public class Collect {

    /**
     * 串行较简单，这里举下并行的例子
     * 模拟Filter查找其中含有字母a的所有元素，打印结果将是aa ab ad
     */
    public void collect_parallel() {
        Stream<String> s1 = Stream.of("aa", "ab", "c", "ad");
        Predicate<String> predicate = t -> t.contains("a");
        System.out.println(s1.parallel().collect(() -> new ArrayList<String>(),
                (array, s) -> {if(predicate.test(s)) array.add(s);},
                (array1, array2) -> array1.addAll(array2)));
    }

    /**
     * 上面方法的非lambda形式
     */
    public void collect_parallel2() {
        Stream<String> s1 = Stream.of("aa", "ab", "c", "ad");
        Predicate<String> predicate = t -> t.contains("a");
        System.out.println(s1.parallel().collect(new Supplier<ArrayList<String>>() {
            @Override
            public ArrayList<String> get() {
                return new ArrayList<String>();
            }
        }, new BiConsumer<ArrayList<String>, String>() {
            @Override
            public void accept(ArrayList<String> r, String s) {
                if(predicate.test(s))
                    r.add(s);
            }
        }, new BiConsumer<ArrayList<String>, ArrayList<String>>() {
            @Override
            public void accept(ArrayList<String> strings, ArrayList<String> strings2) {
                strings.addAll(strings2);
            }
        }));
    }

    public static void main(String... args) {
        Collect c = new Collect();
        c.collect_parallel();
        c.collect_parallel2();
    }
}
